
/***************************************************************************
 *   Copyright (C) 1997 to 2004 by Jonathan Duddington                     *
 *   email: jonsd@users.sourceforge.net                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write see:                           *
 *               <http://www.gnu.org/licenses/>.                           *
 ***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "bbc.h"
#include "dbox.h"
#include "menu.h"
#include "werr.h"
#include "wimp.h"
#include "template.h"
#include "os.h"
#include "xferrecv.h"
#include "xfersend.h"
#include "flex.h"

#include "narc.h"
#include "hdrs.h"

#ifdef MemCheck
#include "MemCheck:Flex.h"
#endif


extern char *decode_date(int date,int timeflag);
extern char *expand_source(int source, int explan);
extern void list_enumerate_start(FOLDREC *fr);
extern CARD *list_enumerate_next(FOLDREC *fr,unsigned int *ixlist);
extern int warea_to_line(TEXTR *t, int wa_y, int *y_out, int *index_out, int height);
extern char *addr_lookup(char *name);
extern char *make_legal_fname(char *fname);
extern char *reply_extract_email_addr(char *buf, int control);

extern int fopen_errnum;
extern int os_version;
extern TEXTR text_rec_temp;
extern OPTIONS options;
extern int dbox_menu_field;
extern BOX box_table[N_BOXES];
extern CARDFILE_REC cardfile[];

dbox dbox_save_text;
dbox dbox_export;

static char *err_saver = "To save, drag the icon to the directory viewer you wish to save to.";
char fname_export[128]= {0};
static char *url_save_string = NULL;


typedef struct dbox__str {
	struct dbox__str *next;  /* if user wants to link dboxes into a list */
	wimp_w w;                /* only used in live dialog boxes */
	int posatcaret;          /* Every time it is shown, it appears "near" the
                            * caret.
                            */
	int showing;
	wimp_caretstr caretstr;   /* save between fillin's. */
	dbox_handler_proc eventproc;
	void *eventprochandle;
	dbox_raw_handler_proc raweventproc;
	void *raweventprochandle;

	dbox_field field;     /* button last pressed */
	int fieldwaiting;     /* a button waiting to be picked up */
	int eventdepth;       /* for delaying disposal */
	int disposepending;

	char name[12];
	char *workspace;
	int workspacesize;
	wimp_wind window;
	/* any icons follow directly after this. */
} dbox__str;
/* Abstraction: a dbox is really a dbox__str*. */



void set_filetype_icon(dbox d, int icon, int filetype)
/***********************************************/
{
	wimp_icon *iptr;

	iptr = ((wimp_icon *) (&d->window + 1)) + icon;
	sprintf(iptr->data.indirecttext.validstring,"Sfile_%.3x",filetype);

}   /* end of set_filetype_icon */




/************************************************************************/
/*  EXPORT TEXT  */
/************************************************************************/



static void save_pluto_status(FILE *f, CARD_EXPANDED *cardex)
/***********************************************************/
{
	char string[4];

	char *p;

	string[0] = 'R';  /* read */
	p = &string[1];

	if(cardex->status == STATUS_LOCKED)
		string[0] = 'L';
	else if(cardex->status == STATUS_MARKED)
		string[0] = 'F';
	else if(cardex->status <= STATUS_UNREAD)
	{
		string[0] = 'U';
		if(cardex->status > STATUS_NEW)
			*p++ = 'O';   /* "old" */
	}


	if(cardex->replied)
	{
		*p++ = 'A';
	}
	if(cardex->status_other & STATUS_BIT_OG)
	{
		*p++ = 'G';
	}

	*p = 0;
	fprintf(f,"X-Status: %s\n",string);
}   /* end of save_pluto_status */




static void save_short_header(FILE *f, CARD_EXPANDED *cardex, int outgoing, int control)
/**************************************************************************************/
/* Control: 1= used in export full header */
{
	char *p;
	char *direction;
	char *user_label;
	char *re;
	int  write_user = 0;
	OPTIONS_MAILBOX *mbox;
	char buf[128];

	if(outgoing & STATUS_BIT_OG)
	{
		user_label = "From";
		if(outgoing & STATUS_BIT_NEWS)
			direction = "Newsgroups";
		else
			direction = "To";
	}
	else
	{
		direction = "From";
		user_label = "To";
	}

	strcpy(buf,cardex->author);
	if(strchr(cardex->author,'@')==NULL)
	{
		p = addr_lookup(cardex->author);
		if(p != NULL)
		{
			sprintf(buf,"%s <%s>",cardex->author,p);
		}
	}

	if((control == 1) && (outgoing & STATUS_BIT_OG))
		write_user = 1;
	else
		fprintf(f,"%s: %s\n",direction,buf);

	if(control == 0)
		write_user = 1;

	if(write_user)
	{
		if(cardex->user > 0)
		{
			mbox = &options.mailbox[cardex->user-1];
			fprintf(f,"%s: %s\n",user_label,mbox->email_addr);
		}
	}

	if(cardex->reply)
		re = "Re: ";
	else
		re = "";
	fprintf(f,"Subject: %s%s\n",re,cardex->title);

	if(control==0)
		fprintf(f,"Date: %s\n",decode_date(cardex->date,4));

	if(control == 0)
	{
		if((outgoing & STATUS_BIT_OG) && (outgoing & STATUS_BIT_NEWS))
		{
		}
		else
		{
			if(cardex->source > 0)
			{
				if(cardex->status_other & STATUS_BIT_NEWS)
					p = "Newsgroups";
				else
					p = "Source";

				fprintf(f,"%s: %s\n",p,expand_source(cardex->source,0));
			}
		}
	}

	if(cardex->ftype == 1)
	{
		fprintf(f,"Content-Type: text/html\n");
	}

	if(cardex->cats[0] != 0)
	{
		fprintf(f,"X-Categories: %s\n",cardex->cats);   /* ???? */
	}
	if(cardex->keywords[0] != 0)
	{
		fprintf(f,"Keywords: %s\n",cardex->keywords);
	}

	if(control == 0)
		fputc('\n',f);
}   /* end of save_short_header */



void list_export_list(FOLDREC *fr)
/********************************/
{
	int  ix;
	FILE *f;
	int  max_line;
	int  count;
	int  level;
	CARD *cptr;
	char *fname;

	fname = get_temp_fname();
	f = fopen_werr(fname,"w",NULL);
	if(f == NULL)
		return;

	max_line = fold_n_lines(fr,0) - 1;

	ix = fold_line_to_ref(fr, 0, &level, NULL);

	if(ix >= 0)
	{
		for(count=0; count<max_line; count++)
		{
			cptr = cardfile_cptr(fr,ix);


			display_line(fr, -1, 0, cptr, level, ix, (wimp_redrawstr *)f, 0,0,0);
			fputc('\n',f);

			ix = fold_next(fr, ix, &level);
			if((ix < 0) || (level < 0))
				break;
		}
	}
	fclose(f);

	OLE_start(fname,0xfff,3,NULL,0,(void *)fr);

}   /* end of list_export_list */




static BOOL export_saver(char *filename, void *handle)
/****************************************************/
{
	CARD_EXPANDED *cardex;
	TEXTR *t;
	FILE *f;
	CARD *cptr;
	int  i;
	char *p;
	int  ix;
	int  count=0;
	int  show_header;
	int  failed_articles;
	int  export_options;
	int  header_written;
	int  header_length;
	char *p2;
	int  length;
	int  skip;
	int  remember_fname=0;
	int  filetype = 0xfff;
	char *addr;

	FOLDREC *fr;
	os_filestr filestr;

	CARD_EXPANDED card_expanded;

	static char *ignore_hdrs[] = {
		"subject:",
		"from:",
		"keywords:",
		"x-status:",
		"status:",
		NULL
	};


	if(check_lock_lists(0xffff) != 0)
		return(FALSE);

	fr = (FOLDREC *)handle;
	t = &text_rec_temp;
	t->fr = fr;
	cardex = &card_expanded;


	if(strcmp_lc(filename,"<wimp$scrap>") != 0)
	{
		if(strchr(filename,'.')==NULL)
		{
			/* no "." in filename, not a pathname */
			werr(0,err_saver);
			return(FALSE);
		}
		remember_fname=1;
	}


	f = fopen_werr(filename,"w","");
	if(f == NULL)
	{
		return(FALSE);
	}

	set_lock_lists(4,fr);

	if(remember_fname)
		strcpy(fname_export,filename);

	failed_articles = 0;
	list_enumerate_start(fr);

	while((cptr = list_enumerate_next(fr,fr->ixlist)) != NULL)
	{
		count++;
		export_options = options.export_options;

		unpack_card(cptr, cardex);
		if(article_read(t,cardex->addr,cardex->docbox,cardex->text_offset,cardex->text_length,0,0,1) < 0)
		{
			failed_articles++;
			continue;
		}

		show_header= 0;

		call_event_process(0);

		if(count > 1)
		{
			if(export_options & SAVE_FORMFEEDS)
			{
				fputc('\f',f);   /* formfeed separator */
			}
			else
			{
				if((export_options & (SAVE_RNEWS | SAVE_FROM)) == 0)
					fprintf(f,"\n");
			}
		}

		if(export_options & SAVE_RNEWS)
		{
			if(cptr->status & STATUS_BIT_NEWS)
				fprintf(f,"#! rnews\n");
			else
				fprintf(f,"#! rmail\n");
		}
		else if(export_options & SAVE_FROM)
		{
			addr = reply_extract_email_addr(cardex->author,3);
			if(addr==NULL)
				addr = "unknown@xxx.invalid";

			fprintf(f,"From %s %s\n",addr,decode_date(cardex->date,0xf));
			filetype = 0xb86;  /* Marcel */
		}

		if(((cptr->user & INET_HDR_MASK) == 0) &&
				((export_options & (SAVE_ORIGHDR | SAVE_INTERNET)) != 0))
		{
			/* no internet header, use short header */
			save_short_header(f, cardex, cardex->status_other,0);
			if(export_options & SAVE_INTERNET)
				save_pluto_status(f,cardex);
			fputc('\n',f);

			export_options |= SAVE_SHORTHDR;
			export_options &= ~(SAVE_ORIGHDR | SAVE_INTERNET);
		}
		else if(export_options & SAVE_SHORTHDR)
		{
			/* short header specified, or internet header required when there is none */
			save_short_header(f, cardex, cardex->status_other,0);
		}
		if(export_options & SAVE_SUBJ_HDR)
		{
			fprintf(f,"%s\n\n",cardex->title);
		}

		if((cptr->user & INET_HDR_MASK) && ((export_options & SAVE_ORIGHDR)==0))
		{
			header_written = 0;
			p = t->text_base;
			length = t->text_length;
			header_length = -1;

			for(i=0; i<(length-1); i++)
			{
				skip=0;
				if((i == 0) || (p[i-1] == '\n'))
				{
					if(p[i]=='\n')
					{
						/* end of header */
						header_length += (i+2);

						if(export_options & SAVE_INTERNET)
						{
							save_pluto_status(f,cardex);
							fputc('\n',f);
						}
						break;
					}


					/* omit certain lines in the header */
					if((export_options & SAVE_INTERNET)==0)
					{
						skip = 1;   /* skip all the header */
					}
					else
					{
						for(ix=0; (p2=ignore_hdrs[ix])!=NULL; ix++)
						{
							if(memcmp_lc(&p[i],p2,strlen(p2))==0)
							{
								skip = 1;
								if(header_written == 0)
									save_short_header(f, cardex, cardex->status_other,1);
								header_written = 1;
								break;
							}
						}
					}
					if(skip)
					{
						/* skip this line */
						for(; i<length; i++)
						{
							if((p[i] == '\n') && (p[i+1] != ' ') && (p[i+1] != '\t'))
							{
								break;
							}
						}
					}
				}
				if(skip==0)
					fputc(p[i],f);
			}

			if((header_written == 0) && (export_options & SAVE_INTERNET))
			{
				save_short_header(f, cardex, cardex->status_other,1);
			}


			if(header_length > 0)
			{
				t->text_start += header_length;
				t->text_length -= header_length;
			}
		}



#ifdef deleted
		if(!(export_options & SAVE_INTERNET) && (cptr->user & INET_HDR_MASK))
		{
			/* skip internet header */
			p = &t->text_base[t->text_start];
			for(i=0; i<t->text_length-1; i++)
			{
				if((p[i] == '\n') && (p[i+1] == '\n'))
				{
					t->text_start += (i+2);
					t->text_length -= (i+2);
					break;
				}
			}
		}
#endif


		/* save text */
		if(export_options & SAVE_REMOVESIG)
		{
			if((i = text_find_sig(t->text_base+t->text_start,t->text_length)) != 0)
				t->text_length = i;

			/* remove attachments too */
			if((t->attachments > 0) && (t->text_length > t->attach[0].displ))
				t->text_length = t->attach[0].displ;

		}
		if(fwrite_werr(t->text_base+t->text_start,1,t->text_length,f) < 0)
			break;

		fprintf(f,"\n");
	}

	if(failed_articles > 0)
	{
		werr(0,"Failed to read %d articles",failed_articles);
	}

	fclose(f);
	options_save();

	clear_lock_lists(4);

	/* we now need to set the filetype, in case the file previously existed with
	   a different filetype */
	filestr.action = 18;   /* set filetype */
	filestr.name = filename;
	filestr.loadaddr = filetype;
	os_file(&filestr);

	dbox_dispose(&dbox_export);
	dbox_export = NULL;

	if(t->text_base != NULL)
	{
		flex_free((flex_ptr)&t->text_base);
		t->text_base = NULL;
	}
	t->text_buf_size = 0;

	return(TRUE);
}   /* end of export_saver */



static BOOL export_saver2(char *filename, void *handle)
/*****************************************************/
{
	wimp_mousestr mousestr;


	/* check that we're not dragging onto the dbox window */
	wimp_get_point_info(&mousestr);
	if(mousestr.w == dbox_syshandle(dbox_export))
		return(FALSE);

	return(export_saver(filename,handle));
}   /* end of export_saver2 */




static void start_export(dbox dbox_export, wimp_eventstr *e, FOLDREC *fr)
/****************************************************************/
{
	int  i;
	int  length = -1;

	options.export_options = 0;
	for(i=0; i<10; i++)
	{
		options.export_options |= dbox_getnumeric(dbox_export,i+6) << i;
	}
	dbox_getfield(dbox_export,4,fname_export,sizeof(fname_export));


	if(e == NULL)
		export_saver(fname_export,(void *)fr);
	else
		xfersend(0xfff,fname_export,length,export_saver2,0,0,e,(void *)fr);

}   /* end of start_export */




static BOOL export_window_handler(dbox d, void *event, void *handle)
/***********************************************************/
{
	wimp_eventstr *e;
	FOLDREC *fr;

	e = (wimp_eventstr *)event;
	fr = (FOLDREC *)handle;

	/* look for mouse drag event */
	switch (e->e)
	{
	case wimp_EBUT:
		if(e->data.but.m.bbits & 0x50)
		{
			start_export(d,e,fr);
			return(TRUE);
		}
		break;
	}

	return(help_handler(event,HELP_EXPORT));
}   /* end of export_window_handler */




void list_export_articles(FOLDREC *fr, int from_menu)
/***************************************************/
{
	int  field;
	char *p;

	if(check_lock_lists(0xffff) != 0)
		return;

	dbox_export = dbox_new("Export");

	p = fname_export;
	if(p[0]==0)
		dbox_getfield(dbox_export,4,fname_export,sizeof(fname_export));
	else
		dbox_setfield(dbox_export,4,p);

	for(field=0; field<10; field++)
	{
		dbox_setnumeric(dbox_export,field+6,(options.export_options>>field)&1);
	}

	dbox_show(dbox_export);
	if(!from_menu)
		set_dbox_at_pointer(dbox_export);

	dbox_raw_eventhandler(dbox_export,export_window_handler,(void *)fr);

	field = dbox_fillin(dbox_export);

	if(field == 0)
	{
		start_export(dbox_export,NULL,fr);
	}

	if(dbox_export != NULL)
		dbox_dispose(&dbox_export);
}   /* end of list_export_articles */




/************************************************************************/
/*  SAVE ATTACHMENTS  */
/************************************************************************/


void make_unique_fname(char *filename, char *directory, char *leafname)
/*********************************************************************/
{
	int  len;
	int  max_len=0;
	int  namesearch;

	if(directory[len = strlen(directory)-1] == '.')
		directory[len] = 0;

	for(namesearch=1; namesearch < 100; namesearch++)
	{
		sprintf(filename,"%s.%s",directory,leafname);
		if(get_filetype(filename) < 0)
			break;  /* this filename is not already in use */

		if(max_len == 0)
		{
			len = strlen(leafname);
			max_len = 10;

			if(memcmp(directory,"raFS::",6)==0)
				max_len = 64;
			else if(get_filetype(directory) == 0xddc)
				max_len = 20;        /* Archive */
			else if(os_version >= 0xa8)
				max_len = 64;  /* RISC Os 4 allows longer leaf names */
		}

		/* file already exists for this attachment name */
		if(namesearch>9)
		{
			if(len > (max_len-3)) len = max_len-3;
		}
		else
		{
			if(len > (max_len-3)) len = max_len-2;
		}
		sprintf(&leafname[len],"~%d",namesearch);  /* append  ~1, ~2, etc */
	}
}   /* end of make_unique_fname */




static BOOL export_attach_saver(char *directory, void *handle)
/***********************************************************/
{
	CARD_EXPANDED *cardex;
	TEXTR *t;
	CARD *cptr;
	int  a_ix;   /* attachment number */
	ATTACHMENT *a;
	int  count=0;
	int  failed_articles;
	int  endflag=0;
	char *leafname;
	int  filetype = 0xfff;
	char filename[256];

	FOLDREC *fr;

	CARD_EXPANDED card_expanded;


	if(check_lock_lists(0xffff) != 0)
		return(FALSE);

	fr = (FOLDREC *)handle;
	t = &text_rec_temp;
	t->fr = fr;
	cardex = &card_expanded;


	if(strcmp_lc(directory,"<wimp$scrap>") != 0)
	{
		if(strchr(directory,'.')==NULL)
		{
			/* no "." in filename, not a pathname */
			werr(0,err_saver);
			return(FALSE);
		}
	}

	filetype = get_filetype(directory);

	set_lock_lists(4,fr);

	failed_articles = 0;
	list_enumerate_start(fr);

	while((endflag==0) && ((cptr = list_enumerate_next(fr,fr->ixlist)) != NULL))
	{
		count++;

		unpack_card(cptr, cardex);
		if(article_read(t,cardex->addr,cardex->docbox,cardex->text_offset,cardex->text_length,0,0,failed_articles) < 0)
		{
			failed_articles++;
			continue;
		}

		text_interpret_article(t,cardex,0);
		for(a_ix=0; a_ix<t->attachments; a_ix++)
		{
			a = &t->attach[a_ix];
			leafname = make_legal_fname(a->name);

			make_unique_fname(filename,directory,leafname);
			if(attachment_save(filename,t,a_ix) == FALSE)
			{
				/* failed to save the file, check for directory-full and abandon */
				if(fopen_errnum == 78259)
				{
					endflag = 1;
					break;
				}
			}
			call_event_process(0);
		}

		call_event_process(0);
	}

	if(failed_articles > 0)
	{
		werr(0,"Failed to read %d articles",failed_articles);
	}

	clear_lock_lists(4);

	if(dbox_export != NULL)
	{
		dbox_dispose(&dbox_export);
		dbox_export = NULL;
	}

	if(t->text_base != NULL)
	{
		flex_free((flex_ptr)&t->text_base);
		t->text_base = NULL;
	}
	t->text_buf_size = 0;

	return(TRUE);
}   /* end of export_attach_saver */




static BOOL export_attach_saver2(char *filename, void *handle)
/************************************************************/
{
	wimp_mousestr mousestr;


	/* check that we're not dragging onto the dbox window */
	wimp_get_point_info(&mousestr);
	if(mousestr.w == dbox_syshandle(dbox_export))
		return(FALSE);

	return(export_attach_saver(filename,handle));
}   /* end of export_attach_saver2 */




static void start_export_attach(dbox dbox_export, wimp_eventstr *e, FOLDREC *fr)
/******************************************************************************/
{
	int  length = -1;

	if(e == NULL)
		export_attach_saver(fname_export,(void *)fr);
	else
		xfersend(0xfff,"",length,export_attach_saver2,0,0,e,(void *)fr);

}   /* end of start_export_attach */




static BOOL export_attach_window_handler(dbox d, void *event, void *handle)
/*************************************************************************/
{
	wimp_eventstr *e;
	FOLDREC *fr;

	e = (wimp_eventstr *)event;
	fr = (FOLDREC *)handle;

	/* look for mouse drag event */
	switch (e->e)
	{
	case wimp_EBUT:
		if(e->data.but.m.bbits & 0x50)
		{
			start_export_attach(d,e,fr);
			return(TRUE);
		}
		break;
	}

	return(help_handler(event,HELP_EXPORT));
}   /* end of export_attach_window_handler */




void list_export_attachments(FOLDREC *fr)
/***************************************/
{
	int  field;

	if(check_lock_lists(0xffff) != 0)
		return;

	dbox_export = dbox_new("SaveAs");
	dbox_setfield(dbox_export,2,"");

	dbox_show(dbox_export);

	dbox_raw_eventhandler(dbox_export,export_attach_window_handler,(void *)fr);

	field = dbox_fillin(dbox_export);

	if(field == 0)
	{
		start_export_attach(dbox_export,NULL,fr);
	}

	if(dbox_export != NULL)
	{
		dbox_dispose(&dbox_export);
		dbox_export = NULL;
	}
}   /* end of list_export_attachments */




int list_export_menu_proc(FOLDREC *fr, char *hit)
/***********************************************/
{
	switch(hit[1])
	{
	case 1:
		list_export_articles(fr,1);
		return(0);

	case 2:
		list_export_attachments(fr);
		return(0);

	case 3:
		list_export_multipart(fr,1);
		return(0);

	case 4:
		list_export_list(fr);
		break;
	}
	return(1);
}   /* end of list_export_menu_proc */




/************************************************************************/
/*  SAVE TEXT  */
/************************************************************************/




static BOOL saver_proc(char *filename, void *handle)
/**************************************************/
{
	FILE *f_out;
	int  start;
	int  end;
	int  i;
	int  outgoing=0;
	TEXTR *t;
	int  full_path = 1;

	t = (TEXTR *)handle;

	if(strchr(filename,'.') == NULL)
	{
		full_path = 0;

		if(strcmp_lc(filename,"<wimp$scrap>") != 0)
		{
			/* no "." in filename, not a pathname */
			werr(0,err_saver);
			return(FALSE);
		}
	}

	f_out = fopen_werr(filename,"w","");
	if(f_out == NULL)
	{
		return(FALSE);
	}


	if(t->selection == 0)
	{
		start = t->text_start;
		end = t->text_length;

		if(options.save_options & SAVE_REMOVESIG)
		{
			end = t->text_body_end;

			i = text_find_sig(t->text_base+start, end-start);
			if(i > 0)
				end = start + i;
		}
		if(full_path)
			strcpy(t->fname_save,filename);


		/*      t->changed = 0;   */
	}
	else
	{
		start = t->region_start;
		end = t->region_end;
	}


	if((t->internet_header <= t->text_start) &&
			(options.save_options & SAVE_SHORTHDR))
	{
		if(t->text_type == X_MAIL)
			outgoing = STATUS_BIT_OG;
		else if(t->text_type == X_NEWS)
			outgoing = STATUS_BIT_OG | STATUS_BIT_NEWS;
		else
			outgoing = t->cardex->status_other;

		save_short_header(f_out, t->cardex, outgoing,0);
	}


	fwrite_werr(&t->text_base[start], 1, end-start, f_out);
	fclose(f_out);

	options_save();

	/* we now need to set the filetype, in case the file previously existed with
	   a different filetype */
	set_filetype(filename,t->filetype);

	if(dbox_save_text != NULL)
	{
		dbox_dispose(&dbox_save_text);
		dbox_save_text = NULL;
	}
	return(TRUE);
}   /* end of saver_proc */




static BOOL saver_proc2(char *filename, void *handle)
/***************************************************/
{
	wimp_mousestr mousestr;

	/* check that we're not dragging onto the dbox window */
	wimp_get_point_info(&mousestr);
	if(mousestr.w == dbox_syshandle(dbox_save_text))
		return(FALSE);

	return(saver_proc(filename,handle));
}   /* end of saver_proc2 */



#ifdef deleted

static BOOL sender_proc(void *handle, int *maxbuf)
/*****************************************/
/* Send data */
{
	int  start;
	int  end;
	int  i;
	int  length;
	TEXTR *t;

	t = (TEXTR *)handle;

	if(t->selection == 0)
	{
		start = t->text_start;
		end = t->text_length;

		if(options.save_options & SAVE_REMOVESIG)
		{
			end = t->text_body_end;
			i = text_find_sig(t->text_base+start, end-start);
			if(i > 0)
				end = start + i;
		}
	}
	else
	{
		start = t->region_start;
		end = t->region_end;
	}

	while(start<=end)
	{
		length = end - start;
		if(length > *maxbuf)
			length = *maxbuf;

		if(!xfersend_sendbuf(&t->text_base[start],length))
			return(FALSE);
		else
		{
			start += length;
			if(length == 0)
				break;
		}
	}


	dbox_dispose(&dbox_save_text);
	dbox_save_text = NULL;

	options_save();
	return(TRUE);
}   /* end of sender_proc*/

#endif




static BOOL check_selection_exists(TEXTR *t)
/***********************************/
{
	if(t->region_end <= 0)
	{
		werr(0,"No selection has been marked");
		return(FALSE);
	}
	return(TRUE);
}   /* end of check_selection_exists */



static void start_save(dbox dbox_save, wimp_eventstr *e, TEXTR *t)
/*********************************************************/
{
	int  length;
	char filename[256];

	t->selection = dbox_getnumeric(dbox_save,4);

	options.save_options = 0;
	if(dbox_getnumeric(dbox_save,5))
		options.save_options = SAVE_SHORTHDR;
	if(dbox_getnumeric(dbox_save,6))
		options.save_options |= SAVE_REMOVESIG;
	dbox_getfield(dbox_save,2,filename,sizeof(filename));


	if(t->selection)
	{
		if(check_selection_exists(t) == FALSE)
			return;

		length = t->region_end - t->region_start;
	}
	else
	{
		length = t->text_length - t->text_start;
	}

	if(e == NULL)
		saver_proc(filename,(void *)t);
	else
	{
		if(options.save_options & SAVE_SHORTHDR)
			xfersend(t->filetype,filename,length,saver_proc2,NULL,0,e,(void *)t);
		else
			xfersend(t->filetype,filename,length,saver_proc2,NULL,0,e,(void *)t);  /* removed sender_proc, was causing problem, not removing temporary handler in xfersend */
	}

}   /* end of start_save */




static BOOL save_window_handler(dbox d, void *event, void *handle)
/*********************************************************/
{
	wimp_w w_dbox;
	wimp_eventstr *e;
	int  selection;
	TEXTR *t;

	e = (wimp_eventstr *)event;
	t = (TEXTR *)handle;

	/* look for mouse drag event */
	switch (e->e)
	{
	case wimp_EKEY:
		break;

	case wimp_EBUT:
		if(e->data.but.m.bbits & 0x50)
		{
			start_save(d,e,t);
			return(TRUE);
		}
		else
		{
			w_dbox = dbox_syshandle(d);

			/* click on icon.
			   get icon number.  set filename depending on 'selection' state */
			switch(e->data.but.m.i)
			{
			case 4:   /* selection button */
				/* read icon state and set 'selection' */

				selection = get_button_state(w_dbox,4);
				if(selection)
				{
					if(check_selection_exists(t) == FALSE)
					{
						set_button_state(w_dbox,4,0,wimp_ISELECTED);
					}
					else
					{
						dbox_getfield(d,2,t->fname_save,sizeof(t->fname_save));  /* remember fname in dbox */
						dbox_setfield(d,2,"Selection");
						dbox_setnumeric(d,5,0);    /* short header */
					}
				}
				else
					dbox_setfield(d,2,t->fname_save);
				break;
			}
		}
		break;


	}

	return(FALSE);
	/* now call the help handler */
	/*   return(help_handler(d, event, (void *)DBOX_SAVE)); */
}   /* end of save_window_handler */






void save_text(TEXTR *t, int from_menu)
/*************************************/
{
	int  field;
	wimp_w w_dbox;
	char path[256];

	if((t->region_end <= 0) || (t->region_start > t->internet_header))
		text_reset_header_order(t);

	dbox_save_text = dbox_new("SaveText");
	w_dbox = dbox_syshandle(dbox_save_text);

	if(t->fname_save[0] != 0)
	{
		strcpy(path,t->fname_save);
	}
	else
	{
		path[0] = 0;
		if(options.save_path[0] != 0)
			sprintf(path,"%s.",options.save_path);

		if(t->text_type <= X_VIEW2)
		{
			strcat(path,"Article");
		}
		else
		{
			strcat(path,"ArticleOut");
		}
		strcpy(t->fname_save,path);
	}

	if(t->region_end > 0)
	{
		strcpy(path,"Selection");
	}

	dbox_setfield(dbox_save_text,2,path);
	dbox_setnumeric(dbox_save_text,5,(options.save_options & SAVE_SHORTHDR) ? 1:0);   /* short header */
	dbox_setnumeric(dbox_save_text,6,(options.save_options & SAVE_REMOVESIG) ? 1:0);   /* remove sig */

	set_filetype_icon(dbox_save_text,3,t->filetype);

	if(t->region_end <= 0)
	{
		/* no region is selected, grey out 'selection' option */
		set_button_state(w_dbox,4,1,wimp_INOSELECT);
	}
	else
	{
		dbox_setnumeric(dbox_save_text,4,1);   /* set 'selection' option */
	}

	dbox_show(dbox_save_text);
	if(!from_menu)
		set_dbox_at_pointer(dbox_save_text);

	dbox_raw_eventhandler(dbox_save_text,save_window_handler,(void *)t);

	field = dbox_fillin(dbox_save_text);

	if(field == 0)
	{
		start_save(dbox_save_text,NULL,t);
	}

	if(dbox_save_text != NULL)
		dbox_dispose(&dbox_save_text);
}   /* end of save_text */






/************************************************************************/
/*  SAVE URL  */
/************************************************************************/







static BOOL url_saver_proc(char *filename, void *handle)
/******************************************************/
{
	FILE *f_out;
	TEXTR *t;

	t = (TEXTR *)handle;

	if(strchr(filename,'.') == NULL)
	{
		if(strcmp_lc(filename,"<wimp$scrap>") != 0)
		{
			/* no "." in filename, not a pathname */
			werr(0,err_saver);
			return(FALSE);
		}
	}

	f_out = fopen_werr(filename,"w","");
	if(f_out == NULL)
	{
		return(FALSE);
	}

	if(url_save_string != NULL)
	{
		fprintf(f_out,"%s\n",url_save_string);
		free(url_save_string);
	}
	fclose(f_out);

	/* we now need to set the filetype, in case the file previously existed with
	   a different filetype */
	set_filetype(filename,FILETYPE_URL);

	if(dbox_save_text != NULL)
	{
		dbox_dispose(&dbox_save_text);
		dbox_save_text = NULL;
	}
	return(TRUE);
}   /* end of url_saver_proc */




static BOOL url_saver_proc2(char *filename, void *handle)
/***************************************************/
{
	wimp_mousestr mousestr;

	/* check that we're not dragging onto the dbox window */
	wimp_get_point_info(&mousestr);
	if(mousestr.w == dbox_syshandle(dbox_save_text))
		return(FALSE);

	return(url_saver_proc(filename,handle));
}   /* end of url_saver_proc2 */






static void url_start_save(dbox dbox_save, wimp_eventstr *e, TEXTR *t)
/********************************************************************/
{
	int  length;
	char filename[256];


	dbox_getfield(dbox_save,2,filename,sizeof(filename));
	length = t->region_end - t->region_start;

	if(e == NULL)
		url_saver_proc(filename,(void *)t);
	else
	{
		xfersend(t->filetype,filename,length,url_saver_proc2,NULL,0,e,(void *)t);
	}
}   /* end of url_start_save */




static BOOL url_save_window_handler(dbox d, void *event, void *handle)
/********************************************************************/
{
	wimp_eventstr *e;
	TEXTR *t;

	e = (wimp_eventstr *)event;
	t = (TEXTR *)handle;

	/* look for mouse drag event */
	switch (e->e)
	{
	case wimp_EBUT:
		if(e->data.but.m.bbits & 0x50)
		{
			url_start_save(d,e,t);
			return(TRUE);
		}
		break;
	}

	return(FALSE);
	/* now call the help handler */
	/*   return(help_handler(d, event, (void *)DBOX_SAVE)); */
}   /* end of url_save_window_handler */






void save_url(TEXTR *t, char *url)
/********************************/
{
	int  field;
	wimp_w w_dbox;
	char path[256];

	if((url_save_string = malloc(strlen(url)+1)) == NULL)
		return;
	strcpy(url_save_string,url);

	dbox_save_text = dbox_new("SaveAs");
	w_dbox = dbox_syshandle(dbox_save_text);

	strcpy(path,"URL");

	dbox_setfield(dbox_save_text,2,path);

	set_filetype_icon(dbox_save_text,3,FILETYPE_URL);


	dbox_show(dbox_save_text);

	dbox_raw_eventhandler(dbox_save_text,url_save_window_handler,(void *)t);

	field = dbox_fillin(dbox_save_text);

	if(field == 0)
	{
		url_start_save(dbox_save_text,NULL,t);
	}

	if(dbox_save_text != NULL)
		dbox_dispose(&dbox_save_text);
}   /* end of save_url */



